package cn.lzd.mvp.base.struct;

import cn.lzd.mvp.base.net.CommonResBean;
import cn.lzd.mvp.base.net.NetCode;
import cn.lzd.mvp.base.net.NetManager;
import com.blankj.utilcode.util.ToastUtils;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;

import java.lang.reflect.ParameterizedType;
import java.util.Objects;

public abstract class BaseModel<P extends IPresenter, S> implements IModel {
    protected P mPresenter;
    Class<S> serviceClass;

    @SuppressWarnings("unchecked")
    public BaseModel(P mPresenter) {
        this.mPresenter = mPresenter;
        try {
            // 这一段代码，就是反射，通过泛型，获取指定的类
            ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
            if (type == null) {
                throw new RuntimeException("运行异常，初始化失败: " + getClass().getSimpleName());
            }
            serviceClass = (Class<S>) type.getActualTypeArguments()[1];
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //使用Retrofit获取了指定接口的实例
    //通过Service执行某一个请求时，拼接Url并执行网络访问，并将返回结果按指定格式解析并返回
    protected S obtainService() {
        return NetManager.getInstance().bindService(serviceClass);//谁拿到 ，谁指定Service
    }

    /**
     * 检查 code，如果返回值中 code 不是 {@link NetCode#Success} 则通知相应错误信息
     * @param bean 需要检查的code
     * @return 如果成功则为 true
     */
    protected boolean checkCode(CommonResBean<?> bean) {
        String needDisplay = bean.checkCode();
        if (needDisplay == null) {
            return true;
        }
        // 向 presenter 中 增加通知错误信息线程
        mPresenter.addDisposable(Observable.just(needDisplay)
                .observeOn(AndroidSchedulers.mainThread())
                .filter(Objects::nonNull)
                .subscribe(ToastUtils::showShort));
        return false;
    }

    @Override
    public void onDestroy() {
        mPresenter = null;
    }
}
